package com.itcs.app.pay.nowpay.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.itcs.app.pay.model.QrcodePayModel;
import com.itcs.app.pay.model.TradePayModel;
import com.itcs.app.pay.model.TradePayRes;
import com.itcs.app.pay.nowpay.constants.PayChannelType;
import com.itcs.app.pay.nowpay.properties.BsConfig;
import com.itcs.app.pay.nowpay.properties.IXzzfConfig;
import com.itcs.app.pay.nowpay.properties.ZsConfig;
import com.itcs.app.pay.nowpay.service.NowpayService;
import com.itcs.app.util.HttpUtil;
import com.itcs.app.util.MD5Facade;
import com.itcs.box.util.DateUtils;
import com.itcs.box.util.LogUtils;

/**
 * 现在支付服务
 * 
 * @author LiuPeng
 * @date 2018年3月24日
 * 
 */
@Service("nowpayService")
public class NowpayServiceImpl implements NowpayService {

	private Log logger = LogFactory.getLog(getClass());

	@Autowired
	private ZsConfig zsConfig;
	@Autowired
	private BsConfig bsConfig;

	@Override
	public Map<String, String> buildQrcode(QrcodePayModel qrcodePayModel) {
		Map<String, String> qrcodeData = new HashMap<String, String>();
		// 现在支付支付渠道类型
		String payChannelType = PayChannelType.payChannelCode2Type(qrcodePayModel.getPayChannelCode());
		qrcodeData = nowPayGZH(payChannelType, qrcodePayModel.getOrderName(), qrcodePayModel.getOrderDetail(), qrcodePayModel.getTollFare(),
				qrcodePayModel.getReserved(), qrcodePayModel.getTranNO());
		qrcodeData.put("isok", "0");
		return qrcodeData;
	}

	/**
	 * 现在支付 主扫-公众号 参数构建
	 * 
	 * @param payChannelType
	 *            支付渠道
	 * @param mhtOrderName
	 *            订单名称
	 * @param mhtOrderDetail
	 *            订单详情
	 * @param mhtOrderAmt
	 *            订单金额
	 * @param mhtReserved
	 *            商户保留字段
	 * @param mhtOrderNo
	 *            订单号
	 * @return
	 */
	private Map<String, String> nowPayGZH(String payChannelType, String mhtOrderName, String mhtOrderDetail, String mhtOrderAmt, String mhtReserved,
			String mhtOrderNo) {

		String appId = zsConfig.getAppId();
		String appKey = zsConfig.getAppKey();

		// 商户自己的订单数据
		String funcode = IXzzfConfig.FUNCODE_WP001;
		String deviceType = zsConfig.getDeviceType();
		String version = zsConfig.getVersion();
		String mhtCurrencyType = zsConfig.getMhtCurrencyType();
		String outputType = zsConfig.getOutputType();
		String mhtSignType = zsConfig.getMhtSignType();
		String notifyUrl = zsConfig.getNotifyUrl();
		String frontNotifyUrl = zsConfig.getFrontNotifyUrl();
		String mhtCharset = zsConfig.getMhtCharset();
		String mhtOrderType = zsConfig.getMhtOrderType();
		String mhtOrderStartTime = DateUtils.getToday("yyyyMMddHHmmss");

		// 做MD5签名
		Map<String, String> dataMap = new HashMap<String, String>();
		dataMap.put("appId", appId);
		dataMap.put("deviceType", deviceType);
		dataMap.put("funcode", funcode);
		dataMap.put("mhtOrderNo", mhtOrderNo);
		dataMap.put("mhtOrderName", mhtOrderName);
		dataMap.put("version", version);
		dataMap.put("mhtCurrencyType", mhtCurrencyType);
		dataMap.put("mhtOrderAmt", mhtOrderAmt);
		dataMap.put("mhtOrderDetail", mhtOrderDetail);
		dataMap.put("mhtOrderType", mhtOrderType);
		dataMap.put("mhtOrderStartTime", mhtOrderStartTime);
		dataMap.put("notifyUrl", notifyUrl);
		dataMap.put("frontNotifyUrl", frontNotifyUrl);
		dataMap.put("mhtCharset", mhtCharset);
		dataMap.put("outputType", outputType);
		dataMap.put("payChannelType", payChannelType);
		dataMap.put("mhtSignType", mhtSignType);

		// 商户保留域， 可以不用填。 如果商户有需要对每笔交易记录一些自己的东西，可以放在这个里面
		dataMap.put("mhtReserved", mhtReserved);
		String mhtSignature = MD5Facade.getFormDataParamMD5(dataMap, appKey, "UTF-8", "1");
		dataMap.put("mhtSignature", mhtSignature);
		String tollFareYStr = new BigDecimal(mhtOrderAmt).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP).toString();
		dataMap.put("mhtOrderAmtStr", tollFareYStr);
		logger.info(LogUtils.build("nowPayGZH", "现在支付公众号主扫", "参数构建完成", JSON.toJSONString(dataMap)));
		return dataMap;
	}

	@Override
	public TradePayRes tradePay(TradePayModel tradePayModel) {

		// 商户自己的订单数据
		String funcode = IXzzfConfig.FUNCODE_WP001;
		String deviceType = bsConfig.getDeviceType();
		String version = bsConfig.getVersion();
		String mhtOrderType = bsConfig.getMhtOrderType();
		String mhtOrderStartTime = DateUtils.getToday("yyyyMMddHHmmss");
		String notifyUrl = bsConfig.getNotifyUrl();
		String mhtCharset = bsConfig.getMhtCharset();
		String mhtOrderTimeOut = bsConfig.getMhtOrderTimeOut();
		String mhtSignType = bsConfig.getMhtSignType();
		String mhtCurrencyType = bsConfig.getMhtCurrencyType();

		String appId = bsConfig.getAppId();
		String appKey = bsConfig.getAppKey();

		// 现在支付支付渠道类型
		String payChannelType = PayChannelType.payChannelCode2Type(tradePayModel.getPayChannelCode());

		// 做MD5签名
		Map<String, String> dataMap = new HashMap<String, String>();
		dataMap.put("appId", appId);
		dataMap.put("channelAuthCode", tradePayModel.getAuthCode());
		dataMap.put("deviceType", deviceType);
		dataMap.put("funcode", funcode);
		dataMap.put("mhtOrderNo", tradePayModel.getTradeNo());
		dataMap.put("mhtOrderName", tradePayModel.getOrderName());
		dataMap.put("mhtOrderDetail", tradePayModel.getOrderDetail());
		dataMap.put("version", version);
		dataMap.put("mhtCurrencyType", mhtCurrencyType);
		dataMap.put("mhtOrderAmt", String.valueOf(tradePayModel.getOrderAmt()));
		dataMap.put("mhtOrderType", mhtOrderType);
		dataMap.put("mhtOrderStartTime", mhtOrderStartTime);
		dataMap.put("mhtOrderTimeOut", mhtOrderTimeOut);
		dataMap.put("notifyUrl", notifyUrl);
		dataMap.put("mhtCharset", mhtCharset);
		dataMap.put("payChannelType", payChannelType);
		dataMap.put("mhtSignType", mhtSignType);

		// 商户保留域， 可以不用填。 如果商户有需要对每笔交易记录一些自己的东西，可以放在这个里面
		dataMap.put("mhtReserved", tradePayModel.getReserved());
		String mhtSignature = MD5Facade.getFormDataParamMD5(dataMap, appKey, "UTF-8", "2");
		logger.info(LogUtils.build("nowPayBS", "现在支付被扫", "参数构建完成", JSON.toJSONString(dataMap)));
		long startTime = System.currentTimeMillis();
		String response = HttpUtil.httpRequest(IXzzfConfig.REQUEST_URL, IXzzfConfig.REQUEST_METHOD, mhtSignature);
		logger.info(LogUtils.build("nowPayBS", "现在支付被扫", "接口调用完成,耗时:" + (System.currentTimeMillis() - startTime), response));
		JSONObject resObj = JSON.parseObject((loadJson(response)));
		// 响应码
		String rescode = TradePayRes.RESCODE_FAILED;
		// 支付状态
		String payStatus = null;
		// 现在支付流水号 聚合订单号
		String platformOrderNo = null;
		// 渠道订单号,微信或支付宝订单号,支付成功时返回 第三方订单号
		String channelOrderNo = null;
		if ("A001".equals(resObj.getString("responseCode"))) {
			rescode = TradePayRes.RESCODE_SUCCESS;
			payStatus = TradePayRes.PAY_WAIT;
			String transStatus = resObj.getString("transStatus");
			if ("A001".equals(transStatus)) {
				// 支付成功--支付成功
				payStatus = TradePayRes.PAY_SUCCESS;
			} else if ("A002".equals(transStatus) || "A006".equals(transStatus)) {
				// 订单支付失败或者交易关闭--返回失败
				payStatus = TradePayRes.PAY_FAILED;
			}
			platformOrderNo = resObj.getString("nowPayOrderNo");
			channelOrderNo = resObj.getString("channelOrderNo");
		}
		TradePayRes res = new TradePayRes(rescode, payStatus);
		res.setPlatformOrderNo(platformOrderNo);
		res.setChannelOrderNo(channelOrderNo);
		return new TradePayRes(rescode, payStatus);
	}

	private String loadJson(String url) {
		url = url.replace("[", "-");
		url = url.replace("]", "-");
		url = url.replace("#", "-");
		int sun = 0;
		int count = 0;
		String json = "{";
		String data = "";

		StringBuffer sb = new StringBuffer();
		StringBuffer sb2 = new StringBuffer();
		String arry = url;
		// 计算出字符串里有多少个&符号
		for (int i = 0; i < arry.length(); i++) {
			if ("&".equals(arry.substring(i, i + 1))) {
				sun++;
			}
		}
		String a[] = arry.split("[&]");// 以&符号分隔
		// 将分隔出来的字符串加上，
		for (int i = 0; i < sun + 1; i++) {
			String[] strs = a[i].toString().split("[=]");
			if (strs.length > 2) {
				String ss = "";
				for (int j = 0; j < strs.length; j++) {// 有时返回多个=号
					if (j == 0) {
						ss = ss + strs[j] + "=" + strs[j + 1];
					} else {
						if (j == strs.length - 1) {
						} else {
							ss = ss + "|" + strs[j + 1];
						}
					}
				}
				sb.append(ss + ",");
			} else {
				sb.append(a[i] + ",");
			}
		}
		// 以=分隔
		String[] c = sb.toString().split("[=]");
		// 将分隔出来的字符串加上，
		for (int j = 0; j < c.length; j++) {
			sb2.append(c[j] + ",");
		}
		// 去掉最后面两个,
		String result = sb2.toString().substring(0, sb2.length() - 2);
		// 计算出字符串里有多少个,符号
		for (int i = 0; i < result.length(); i++) {
			if (",".equals(result.substring(i, i + 1))) {
				count++;
			}
		}
		// 以，分隔
		String[] d = result.toString().split("[,]");
		for (int i = 0; i < count + 1; i++) {
			if (i % 2 != 0) {// 字符下标为奇数时加上，
				data += "\"" + d[i] + "\",";
			} else {
				data += "\"" + d[i] + "\":";
			}
		}
		// 拼接json格式
		String jsonArray = (json + data).substring(0, (json + data).length() - 1) + "}";
		System.out.println(jsonArray.replace("|", "="));
		return jsonArray.replace("|", "=");
	}

}
